import { EventDefinition } from '@/types/event';
import { dispatchActions } from '../action';
import Node from '../core/Node';

/**
 * 激活的节点/组件
 */
const activeNodes = new Set<Node>();

export const triggerEvent = (nodes: Node[] = [], nodeMap: Map<string, Node> = new Map()) => {
  // 候选的鼠标进入节点
  const mouseenterCandidateNodeSet = new Set<Node>();
  // 候选的鼠标离开节点
  const mouseleaveCandidateNodeSet = new Set<Node>();
  // 动作字典
  const mouseenterActionMap = new Map<string, EventDefinition[]>();
  const mouseleaveActionMap = new Map<string, EventDefinition[]>();

  nodes.forEach((node) => {
    const mouseenterEvents = node.config.events.filter(
      (event: EventDefinition) => event.name === 'mouseenter'
    );
    if (!mouseenterEvents.length) {
      return;
    }
    mouseenterCandidateNodeSet.add(node);
    mouseenterActionMap.set(node.config.id, mouseenterEvents);
  });

  for (const [id, node] of nodeMap) {
    const mouseleaveEvents = node.config.events.filter(
      (event: EventDefinition) => event.name === 'mouseleave'
    );
    // 如果该节点包含在激活的节点中，且本次事件中该节点不属于 enter 节点，判定为 leave 节点
    if (mouseleaveEvents.length && activeNodes.has(node) && !mouseenterCandidateNodeSet.has(node)) {
      mouseleaveActionMap.set(id, mouseleaveEvents);
      mouseleaveCandidateNodeSet.add(node);
    }
  }

  for (const node of mouseenterCandidateNodeSet) {
    activeNodes.add(node);
    const mouseenterEvents = mouseenterActionMap.get(node.config.id)!;
    mouseenterEvents.forEach((event: EventDefinition) => {
      const actions = event.actions || [];
      dispatchActions(actions);
    });
  }

  for (const node of mouseleaveCandidateNodeSet) {
    const mouseleaveEvents = mouseleaveActionMap.get(node.config.id)!;
    mouseleaveEvents.forEach((event: EventDefinition) => {
      const actions = event.actions || [];
      dispatchActions(actions);
    });
  }
};
